package com.yunmai.library.db;

import com.yunmai.library.db.common.Count;
import com.yunmai.library.db.common.DatabaseName;
import com.yunmai.library.db.common.Delete;
import com.yunmai.library.db.common.Insert;
import com.yunmai.library.db.common.Query;
import com.yunmai.library.db.common.Update;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.sql.SQLException;

/**
 * 把接口的方法转换成数据库操作方法
 *
 * @author liyi
 *         create at 2018/3/26
 **/
public final class DatabaseMethod<R, T> {

    final Annotation[] methodAnnotations;
    DBManager dbManager;
    Class entitie;
    Class daoClass;

    DatabaseMethod(Class<?> daoClass, DBManager dbManager, Method method) {
        methodAnnotations = method.getAnnotations();
        this.dbManager = dbManager;
        this.daoClass = daoClass;
        entitie = findEntitie(daoClass);
    }

    /**
     * 获取操作方法对应的实体类
     *
     * @return
     */
    public Class getEntitie() {
        return entitie;
    }

    /**
     * 把接口的方法转换成数据库操作方法
     *
     * @param call
     * @param args
     * @return
     * @throws SQLException
     */
    public Result toCall(Call call, Object[] args) throws SQLException {
        Result result = new Result();
        for (Annotation annotation
            : methodAnnotations) {
            if (annotation instanceof Insert) {
                result.result = call.insert(args[0]);
                break;
            }

            if (annotation instanceof Delete) {
                result.result = call.delete(args[0]);
                break;
            }

            if (annotation instanceof Update) {
                result.result = call.update(args[0]);
                break;
            }

            if (annotation instanceof Count) {
                result.result = call.count();
                break;
            }

            if (annotation instanceof Query) {
                //sql = ((Query) annotation).value();
                String sql = getQuerySql(args,((Query) annotation).value());
                result.result = call.query(sql);
                break;
            }
        }
        return result;
    }

    /**
     * 获取查询sql
     *
     * @param args
     */
    private String getQuerySql(Object[] args,String sql) {
        int argumentCount = args != null ? args.length : 0;

        String[] arguments = new String[argumentCount];

        int start = 0;
        int index = 0;
        while (sql.indexOf(":", start) > 0) {
            if (index >= argumentCount) throw new IllegalArgumentException("Argument Error");
            int indexOf = sql.indexOf(":", start);
            int endOf = sql.indexOf(" ", indexOf);
            if (endOf <= 0) endOf = sql.length();
            String argument = sql.substring(indexOf, endOf);
            start = endOf;
            arguments[index++] = argument;
        }
        if (index != argumentCount) throw new IllegalArgumentException("Argument Error index = "+index+" argumentCount "+argumentCount+" sql= "+sql);

        for (int i = 0; i < argumentCount; i++) {
            sql = sql.replace("" + arguments[i], args[i] + "");
        }
        return sql;
    }

    /**
     * 根据class获取对应的实体类
     *
     * @param daoClass
     * @return
     */
    private Class findEntitie(Class daoClass) {
        Annotation[] animations = daoClass.getAnnotations();
        for (Annotation annotation
            : animations) {
            if (annotation instanceof DatabaseName) {
                return ((DatabaseName) annotation).entitie();
            }
        }

        throw new IllegalArgumentException("DatabaseName Incorrect");
    }
}
